package com.yugu.park.security.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.yugu.park.config.TokenService;
import com.yugu.enums.SysConstants;
import com.yugu.park.enums.UserConstants;
import com.yugu.park.manage.AsyncManager;
import com.yugu.park.manage.factory.AsyncFactory;
import com.yugu.park.security.entity.LoginBody;
import com.yugu.park.security.entity.LoginUser;
import com.yugu.park.security.entity.MetaVo;
import com.yugu.park.security.entity.RouterVo;
import com.yugu.park.security.entity.TSysMenu;
import com.yugu.park.security.entity.TSysUser;
import com.yugu.park.security.service.TSysUserService;
import com.yugu.util.Constants;
import com.yugu.util.ResponseUtil;
import com.yugu.util.StringUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * Rest风格用户的增删改查接口 Swagger2 注解整理
 * ====================================================
 * Api：修饰整个类，描述Controller的作用 ApiOperation：描述一个类的一个方法，或者说一个接口 ApiParam：单个参数描述
 * ApiModel：用对象来接收参数 ApiProperty：用对象接收参数时，描述对象的一个字段 ApiResponse：HTTP响应其中1个描述
 * ApiResponses：HTTP响应整体描述 ApiIgnore：使用该注解忽略这个API ApiError ：发生错误返回的信息
 * ApiImplicitParam：一个请求参数 ApiImplicitParams：多个请求参数
 * ====================================================
 */
@Api(tags = { "登陆和获取当前登陆人信息" })
@RestController
@RequestMapping("/auth")
public class TUserController {
	@Resource
	private TSysUserService service;
	@Autowired
	private TokenService tokenService;

	@ApiOperation(value = "用户登陆", notes = "用户登陆")
	@PostMapping("/login")
	public ResponseUtil.Result<TSysUser> login(ModelMap modelMap, HttpServletRequest request,
			HttpServletResponse response, @RequestBody LoginBody loginBody) {
		String token = service.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getUuid());
		LoginUser loginUser = tokenService.getLoginUser(token);
		// 增加用户认证过期,返回给前端过期标识
		if (ObjectUtil.isNull(loginUser)) {
			String msg = "认证失败，无法访问系统资源";
			return ResponseUtil.addError(msg);
		}
		TSysUser user = loginUser.getSysUser();
		user.setToken(token);

		return ResponseUtil.addSuccess(user);
	}

	@ApiOperation(value = "获取当前用户信息", notes = "获取当前用户信息")
	@PostMapping("/info")
	public ResponseUtil.Result<Map<String, Object>> info(ModelMap modelMap, HttpServletRequest request,
			HttpServletResponse response) {
		LoginUser loginUser = tokenService.getLoginUser(request);
		// 增加用户认证过期,返回给前端过期标识
		if (ObjectUtil.isNull(loginUser)) {
			String msg = "认证失败，无法访问系统资源";
			return ResponseUtil.addError(msg);
		}
		TSysUser user = loginUser.getSysUser();
		// 查看角色
		// 查看权限
		Map<String, Object> result = new HashMap<String, Object>();
		Set<String> pers = service.getUserPermission();
		result.put("user", user);
		result.put("roles", null);
		result.put("permissions", pers);
		return ResponseUtil.addSuccess(result);
	}

	@GetMapping("/getRouters")
	public ResponseUtil.Result<List<RouterVo>> getRouters(HttpServletRequest request, HttpServletResponse response) {
		List<TSysMenu> routers = service.getRouters();
//    	List<RouterVo> result =null;
		return ResponseUtil.addSuccess(buildMenus(routers));
	}

	public List<RouterVo> buildMenus(List<TSysMenu> menus) {
		List<RouterVo> routers = new LinkedList<RouterVo>();
		for (TSysMenu menu : menus) {
			RouterVo router = new RouterVo();
			router.setHidden("1".equals(menu.getVisible()));
			router.setName(getRouteName(menu));
			router.setPath(getRouterPath(menu));
			router.setComponent(getComponent(menu));
			router.setQuery(menu.getQuery());
			router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()),
					menu.getPath()));
			List<TSysMenu> cMenus = menu.getChildren();
			if (cMenus != null && cMenus.size() > 0 && UserConstants.TYPE_DIR.equals(menu.getMenuType())) {
				router.setAlwaysShow(true);
				router.setRedirect("noRedirect");
				router.setChildren(buildMenus(cMenus));
			} else if (isMenuFrame(menu)) {
				router.setMeta(null);
				List<RouterVo> childrenList = new ArrayList<RouterVo>();
				RouterVo children = new RouterVo();
				children.setPath(menu.getPath());
				children.setComponent(menu.getComponent());
				children.setName(StringUtils.capitalize(menu.getPath()));
				children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(),
						StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
				children.setQuery(menu.getQuery());
				childrenList.add(children);
				router.setChildren(childrenList);
			} else if ("0".equals(menu.getParentId()) && isInnerLink(menu)) {
				router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon()));
				router.setPath("/");
				List<RouterVo> childrenList = new ArrayList<RouterVo>();
				RouterVo children = new RouterVo();
				String routerPath = innerLinkReplaceEach(menu.getPath());
				children.setPath(routerPath);
				children.setComponent(UserConstants.INNER_LINK);
				children.setName(StringUtils.capitalize(routerPath));
				children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
				childrenList.add(children);
				router.setChildren(childrenList);
			}
			routers.add(router);
		}
		return routers;
	}

	public String getRouteName(TSysMenu menu) {
		String routerName = StringUtils.capitalize(menu.getPath());
		// 非外链并且是一级目录（类型为目录）
		if (isMenuFrame(menu)) {
			routerName = StringUtils.EMPTY;
		}
		return routerName;
	}

	/**
	 * 是否为内链组件
	 * 
	 * @param menu 菜单信息
	 * @return 结果
	 */
	public boolean isInnerLink(TSysMenu menu) {
		return menu.getIsFrame().equals(UserConstants.NO_FRAME) && StringUtils.ishttp(menu.getPath());
	}

	/**
	 * 是否为菜单内部跳转
	 * 
	 * @param menu 菜单信息
	 * @return 结果
	 */
	public boolean isMenuFrame(TSysMenu menu) {
		return "0".equals(menu.getParentId()) && UserConstants.TYPE_MENU.equals(menu.getMenuType())
				&& menu.getIsFrame().equals(UserConstants.NO_FRAME);
	}

	/**
	 * 获取路由地址
	 * 
	 * @param menu 菜单信息
	 * @return 路由地址
	 */
	public String getRouterPath(TSysMenu menu) {
		String routerPath = menu.getPath();
		// 内链打开外网方式
		if ("0".equals(menu.getParentId()) && isInnerLink(menu)) {
			routerPath = innerLinkReplaceEach(routerPath);
		}
		// 非外链并且是一级目录（类型为目录）
		if ("0".equals(menu.getParentId()) && UserConstants.TYPE_DIR.equals(menu.getMenuType())
				&& UserConstants.NO_FRAME.equals(menu.getIsFrame())) {
			routerPath = "/" + menu.getPath();
		}
		// 非外链并且是一级目录（类型为菜单）
		else if (isMenuFrame(menu)) {
			routerPath = "/";
		}
		return routerPath;
	}

	/**
	 * 内链域名特殊字符替换
	 * 
	 * @return 替换后的内链域名
	 */
	public String innerLinkReplaceEach(String path) {
		return StringUtils.replaceEach(path,
				new String[] { SysConstants.HTTP, SysConstants.HTTPS, SysConstants.WWW, "." },
				new String[] { "", "", "", "/" });
	}

	/**
	 * 获取组件信息
	 * 
	 * @param menu 菜单信息
	 * @return 组件信息
	 */
	public String getComponent(TSysMenu menu) {
		String component = UserConstants.LAYOUT;
		if (StringUtils.isNotEmpty(menu.getComponent()) && !isMenuFrame(menu)) {
			component = menu.getComponent();
		} else if (StringUtils.isEmpty(menu.getComponent()) && "0".equals(menu.getParentId()) && isInnerLink(menu)) {
			component = UserConstants.INNER_LINK;
		} else if (StringUtils.isEmpty(menu.getComponent()) && isParentView(menu)) {
			component = UserConstants.PARENT_VIEW;
		}
		return component;
	}

	/**
	 * 是否为parent_view组件
	 * 
	 * @param menu 菜单信息
	 * @return 结果
	 */
	public boolean isParentView(TSysMenu menu) {
		return (!"0".equals(menu.getParentId())) && UserConstants.TYPE_DIR.equals(menu.getMenuType());
	}

}
